﻿ 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ExtensionHelper
{
    /// <summary>
    /// 
    /// </summary>
    public static class Extension
    {
        /// <summary>
        /// 单项正则匹配
        /// </summary>
        /// <param name="str">需要匹配的字符串</param>
        /// <param name="reg">正则</param>
        /// <param name="regexOptions">匹配配置</param>
        /// <returns></returns>
        public static string RegexMatch(this string str, string reg,RegexOptions regexOptions = RegexOptions.IgnoreCase)
        {
            return Regex.Match(str, reg, regexOptions).Value;
        }

        /// <summary>
        /// 字符串是否跟正则匹配
        /// </summary>
        /// <param name="str">需要匹配的字符串</param>
        /// <param name="reg">正则</param>
        /// <param name="regexOptions">匹配配置</param>
        /// <returns></returns>
        public static bool RegexIsMatch(this string str, string reg, RegexOptions regexOptions = RegexOptions.IgnoreCase)
        {
            return Regex.Match(str, reg, regexOptions).Success;
        }


        /// <summary>
        /// 生成guid
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string NewGuid(this string str)
        { 
            return Guid.NewGuid().ToString().ToUpper();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="table"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(this DataTable table)
        {
            if (table == null)
            {
                return null;
            }

            List<DataRow> rows = new List<DataRow>();

            foreach (DataRow row in table.Rows)
            {
                rows.Add(row);
            }

            return ConvertTo<T>(rows);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rows"></param>
        /// <returns></returns>
        private static List<T> ConvertTo<T>(IList<DataRow> rows)
        {
            List<T> list = null;

            if (rows != null)
            {
                list = new List<T>();

                foreach (DataRow row in rows)
                {
                    T item = CreateItem<T>(row);
                    list.Add(item);
                }
            }

            return list;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <returns></returns>
        private static T CreateItem<T>(DataRow row)
        {
            T obj = default(T);
            if (row != null)
            {
                obj = Activator.CreateInstance<T>();

                foreach (DataColumn column in row.Table.Columns)
                {
                    PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
                    try
                    {
                        object dynmicValue;
                        string sValue = row[column.ColumnName].ToString();
                        //根据属性类型动态转换属性的值
                        if (String.IsNullOrEmpty(sValue))//空值
                            dynmicValue = prop.PropertyType.IsValueType ? Activator.CreateInstance(prop.PropertyType) : null;//值类型
                        else
                            dynmicValue = System.ComponentModel.TypeDescriptor.GetConverter(prop.PropertyType).ConvertFromString(sValue.ToString());//创建对象

                        //调用属性的SetValue方法赋值
                        prop.SetValue(obj, dynmicValue, null);

                        //object value = row[column.ColumnName];
                        //prop.SetValue(obj, value, null);
                    }
                    catch
                    {  //You can log something here     
                       //throw;    
                    }
                }
            }

            return obj;
        }


        /// <summary>
        /// 集合转换为DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this IEnumerable<T> collection)
        {
            var props = typeof(T).GetProperties();
            var dt = new DataTable();
            dt.TableName = typeof(T).Name;
            dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name)).ToArray());
            if (collection.Count() > 0)
            {
                for (int i = 0; i < collection.Count(); i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in props)
                    {
                        object obj = pi.GetValue(collection.ElementAt(i), null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    dt.LoadDataRow(array, true);
                }
            }
            return dt;
        }

        public static bool IsInt(this string s)
        {
            int i = -1;
            return Int32.TryParse(s, out i);
        }

        public static int ToInt(this string s)
        {
            int i = -1;
            return Int32.TryParse(s, out i) ? i : -1;
        }

        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }

        public static List<T> Delete<T>(this List<T> list, Func<T, bool> func)
        {
            for (int i = list.Count - 1; i >= 0; i--)
            {
                if (func(list[i]))
                {
                    list.RemoveAt(i);
                }
            }
            return list;
        }

        public static bool Exists<T>(this List<T> list, Func<T, bool> func)
        {
            for (int i = list.Count - 1; i >= 0; i--)
            {
                if (func(list[i]))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="defaultval"></param>
        /// <returns></returns>
        public static int ToInt(this string str, int defaultval = 0)
        {
            int result = 0;
            if (Int32.TryParse(str, out result))
            {
                return result;
            }
            else
            {
                result = defaultval;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="defaultval"></param>
        /// <returns></returns>
        public static float ToFloat(this string str, float defaultval = 0)
        {
            float result = 0;
            if (float.TryParse(str, out result))
            {
                return result;
            }
            else
            {
                result = defaultval;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="defaultval"></param>
        /// <returns></returns>
        public static double ToDouble(this string str, double defaultval = 0)
        {
            double result = 0;
            if (double.TryParse(str, out result))
            {
                return result;
            }
            else
            {
                result = defaultval;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string str, DateTime dt)
        {
            DateTime result = DateTime.Now;
            try
            {
                result = Convert.ToDateTime(str);
            }
            catch
            {
                result = DateTime.Now;
            }
            return result;
        }

        /// <summary>
        ///   
        /// </summary>
        /// <param name="objects"></param>
        /// <param name="attribute"></param>
        /// <returns></returns>
        public static int IndexOfAttribute(this object[] objects, object attribute)
        {
            if (objects == null || objects.Length == 0)
            {
                return -1;
            }
            for (int i = 0; i < objects.Length; i++)
            {
                if (objects[i].GetType() == attribute.GetType())
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        ///  判断两个类型是否相等，包括可空类型
        /// </summary>
        /// <param name="sourceType"></param>
        /// <param name="cmpType"></param>
        /// <returns></returns>
        public static bool Equal(this Type sourceType, Type cmpType)
        {
            //非可空类型
            if (sourceType.GenericTypeArguments.Length == 0)
            {
                return sourceType.Name == cmpType.Name;
            }
            else
            {
                //可空类型
                return sourceType.GenericTypeArguments[0].Name == cmpType.Name;
            }



        }

        /// <summary>
        /// 重新定义文件名称
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string RandomFileName(this string file)
        {
            return Guid.NewGuid().ToString("N") + System.IO.Path.GetExtension(file);
        }
 

        /// <summary>
        /// 修改文件编码格式
        /// </summary>
        /// <param name="sourcefile">源文件</param>
        /// <param name="encoding">需要转换的编码</param>
        public static void ChangeFileEncoding(this string sourcefile, Encoding encoding)
        { 
            System.IO.FileStream fs = new System.IO.FileStream(sourcefile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            byte[] flieByte = new byte[fs.Length];
            fs.Read(flieByte, 0, flieByte.Length);
            fs.Close();

            StreamWriter docWriter;  
            docWriter = new StreamWriter(sourcefile, false, Encoding.UTF8);
            docWriter.Write(Encoding.UTF8.GetString(flieByte));
            docWriter.Close(); 
        }


        /// <summary>
        /// 获取文件编码格式
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static System.Text.Encoding GetFileEncodeType(this string filename)
        {
            using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
                byte[] buffer = br.ReadBytes(2);

                if (buffer[0] >= 0xEF)
                {
                    if (buffer[0] == 0xEF && buffer[1] == 0xBB)
                    {
                        return System.Text.Encoding.UTF8;
                    }
                    else if (buffer[0] == 0xFE && buffer[1] == 0xFF)
                    {
                        return System.Text.Encoding.BigEndianUnicode;
                    }
                    else if (buffer[0] == 0xFF && buffer[1] == 0xFE)
                    {
                        return System.Text.Encoding.Unicode;
                    }
                    else
                    {
                        return System.Text.Encoding.Default;
                    }
                }
                else
                {
                    return System.Text.Encoding.Default;
                }
            }
        }
    }

}
